/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.crm.cs.web.CsAction
   Module Description   :

   Date Created      : 2009/11/24
   Original Author   : andy.chuang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.crm.cs.web;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.yaodian100.core.admin.entity.User;
import com.yaodian100.core.admin.utils.AdminHelper;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.utils.JspUtil;
import com.yaodian100.crm.cs.entity.CommonQuestionType;
import com.yaodian100.crm.cs.entity.FromChannel;
import com.yaodian100.crm.cs.entity.Question;
import com.yaodian100.crm.cs.entity.QuestionType;
import com.yaodian100.crm.cs.service.CsService;
import com.yaodian100.crm.workorder.entity.WorkOrder;
import com.yaodian100.crm.workorder.service.WorkOrderService;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.service.OrderService;

/**
 * @author andy.chuang
 * 
 */
@Transactional
public class CsAction {
	private String iamlazy;
	@Resource
	private BaseManager baseMgr;
	@Resource
	private WorkOrderService workOrderService;
	@Resource
	private OrderService orderService;
	@Resource
	private CsService csService;
	private String operation;
	private String workFlowName;
	private String showOnQAA;
	private String mustInquire;
	private String class1;
	private String class2;
	private String fromManage;
	private String priority;
	private String workOrderId;
	private String AJAX;
	private String cellPhone;
	private String phoneArea;
	private String phoneExt;
	private String phone;
	private String isProductQAA;
	private String email;
	private String cancelReason;

	// private File batchOrderList;
	private String batchOrderList;
	private int successBatch;
	private int readOrders;
	private int failBatch;
	private String orgQuestionId;
	private String questionId;
	private String forward;

	/**
	 * @return the forward
	 */
	public String getForward() {
		return forward;
	}

	/**
	 * @param forward the forward to set
	 */
	public void setForward(String forward) {
		this.forward = forward;
	}

	/**
	 * @return the questionId
	 */
	public String getQuestionId() {
		return questionId;
	}

	/**
	 * @param questionId the questionId to set
	 */
	public void setQuestionId(String questionId) {
		this.questionId = questionId;
	}

	/**
	 * @return the orgQuestionId
	 */
	public String getOrgQuestionId() {
		return orgQuestionId;
	}

	/**
	 * @param orgQuestionId the orgQuestionId to set
	 */
	public void setOrgQuestionId(String orgQuestionId) {
		this.orgQuestionId = orgQuestionId;
	}

	/**
	 * @return the cancelReason
	 */
	public String getCancelReason() {
		return cancelReason;
	}

	/**
	 * @param cancelReason the cancelReason to set
	 */
	public void setCancelReason(String cancelReason) {
		this.cancelReason = cancelReason;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email the email to set
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	/**
	 * @return the phoneArea
	 */
	public String getPhoneArea() {
		return phoneArea;
	}

	/**
	 * @param phoneArea the phoneArea to set
	 */
	public void setPhoneArea(String phoneArea) {
		this.phoneArea = phoneArea;
	}

	/**
	 * @return the phoneExt
	 */
	public String getPhoneExt() {
		return phoneExt;
	}

	/**
	 * @param phoneExt the phoneExt to set
	 */
	public void setPhoneExt(String phoneExt) {
		this.phoneExt = phoneExt;
	}

	/**
	 * @return the phone
	 */
	public String getPhone() {
		return phone;
	}

	/**
	 * @param phone the phone to set
	 */
	public void setPhone(String phone) {
		this.phone = phone;
	}

	/**
	 * @return the isProductQAA
	 */
	public String getIsProductQAA() {
		return isProductQAA;
	}

	/**
	 * @param isProductQAA the isProductQAA to set
	 */
	public void setIsProductQAA(String isProductQAA) {
		this.isProductQAA = isProductQAA;
	}

	/**
	 * @return the cellPhone
	 */
	public String getCellPhone() {
		return cellPhone;
	}

	/**
	 * @param cellPhone the cellPhone to set
	 */
	public void setCellPhone(String cellPhone) {
		this.cellPhone = cellPhone;
	}

	/**
	 * @return the workOrderId
	 */
	public String getWorkOrderId() {
		return workOrderId;
	}

	/**
	 * @param workOrderId the workOrderId to set
	 */
	public void setWorkOrderId(String workOrderId) {
		this.workOrderId = workOrderId;
	}

	/**
	 * @return the priority
	 */
	public String getPriority() {
		return priority;
	}

	/**
	 * @param priority the priority to set
	 */
	public void setPriority(String priority) {
		this.priority = priority;
	}

	/**
	 * @return the fromManage
	 */
	public String getFromManage() {
		return fromManage;
	}

	/**
	 * @param fromManage the fromManage to set
	 */
	public void setFromManage(String fromManage) {
		this.fromManage = fromManage;
	}

	/**
	 * @return the class1
	 */
	public String getClass1() {
		return class1;
	}

	/**
	 * @param class1 the class1 to set
	 */
	public void setClass1(String class1) {
		this.class1 = class1;
	}

	/**
	 * @return the class2
	 */
	public String getClass2() {
		return class2;
	}

	/**
	 * @param class2 the class2 to set
	 */
	public void setClass2(String class2) {
		this.class2 = class2;
	}

	/**
	 * @return the mustInquire
	 */
	public String getMustInquire() {
		return mustInquire;
	}

	/**
	 * @param mustInquire the mustInquire to set
	 */
	public void setMustInquire(String mustInquire) {
		this.mustInquire = mustInquire;
	}

	/**
	 * @return the showOnQAA
	 */
	public String getShowOnQAA() {
		return showOnQAA;
	}

	/**
	 * @param showOnQAA the showOnQAA to set
	 */
	public void setShowOnQAA(String showOnQAA) {
		this.showOnQAA = showOnQAA;
	}

	/**
	 * @return the workFlowName
	 */
	public String getWorkFlowName() {
		return workFlowName;
	}

	/**
	 * @param workFlowName the workFlowName to set
	 */
	public void setWorkFlowName(String workFlowName) {
		this.workFlowName = workFlowName;
	}

	/**
	 * @return the operation
	 */
	public String getOperation() {
		return operation;
	}

	/**
	 * @param operation the operation to set
	 */
	public void setOperation(String operation) {
		this.operation = operation;
	}

	/**
	 * @return the iamlazy
	 */
	public String getIamlazy() {
		return iamlazy;
	}

	/**
	 * @param iamlazy the iamlazy to set
	 */
	public void setIamlazy(String iamlazy) {
		this.iamlazy = iamlazy;
	}

	private String id;
	private String title;
	private String shortDesc;
	private String description;
	private String questionType;
	private String fromChannel;
	private String memberId;
	// for ProductQAA
	private String productId;
	// for ReturnProduct
	private String returnId;
	// for ChangeProduct
	private String changeId;
	// for CommonQuestion
	private String commonQuestionType;
	private String orderId;
	// for forwardOrder
	private String comment;
	private String responser;
	private String workFlowNodeId;

	// for commonQuestionType
	private String parentId;
	private String name;

	private String sysMessage;
	private String needAnswer;

	/**
	 * @return the needAnswer
	 */
	public String getNeedAnswer() {
		return needAnswer;
	}

	/**
	 * @param needAnswer the needAnswer to set
	 */
	public void setNeedAnswer(String needAnswer) {
		this.needAnswer = needAnswer;
	}

	/**
	 * @return the sysMessage
	 */
	public String getSysMessage() {
		return sysMessage;
	}

	/**
	 * @param sysMessage the sysMessage to set
	 */
	public void setSysMessage(String sysMessage) {
		this.sysMessage = sysMessage;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the parentId
	 */
	public String getParentId() {
		return parentId;
	}

	/**
	 * @param parentId the parentId to set
	 */
	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	/**
	 * @return the comment
	 */
	public String getComment() {
		return comment;
	}

	/**
	 * @param comment the comment to set
	 */
	public void setComment(String comment) {
		this.comment = comment;
	}

	/**
	 * @return the responser
	 */
	public String getResponser() {
		return responser;
	}

	/**
	 * @param responser the responser to set
	 */
	public void setResponser(String responser) {
		this.responser = responser;
	}

	/**
	 * @return the workFlowNodeId
	 */
	public String getWorkFlowNodeId() {
		return workFlowNodeId;
	}

	/**
	 * @param workFlowNodeId the workFlowNodeId to set
	 */
	public void setWorkFlowNodeId(String workFlowNodeId) {
		this.workFlowNodeId = workFlowNodeId;
	}

	/**
	 * @return the commonQuestionType
	 */
	public String getCommonQuestionType() {
		return commonQuestionType;
	}

	/**
	 * @param commonQuestionType the commonQuestionType to set
	 */
	public void setCommonQuestionType(String commonQuestionType) {
		this.commonQuestionType = commonQuestionType;
	}

	/**
	 * @return the changeId
	 */
	public String getChangeId() {
		return changeId;
	}

	/**
	 * @param changeId the changeId to set
	 */
	public void setChangeId(String changeId) {
		this.changeId = changeId;
	}

	/**
	 * @return the returnId
	 */
	public String getReturnId() {
		return returnId;
	}

	/**
	 * @param returnId the returnId to set
	 */
	public void setReturnId(String returnId) {
		this.returnId = returnId;
	}

	/**
	 * @return the orderId
	 */
	public String getOrderId() {
		return orderId;
	}

	/**
	 * @param orderId the orderId to set
	 */
	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	/**
	 * @return the productId
	 */
	public String getProductId() {
		return productId;
	}

	/**
	 * @param productId the productId to set
	 */
	public void setProductId(String productId) {
		this.productId = productId;
	}

	/**
	 * @return the memberId
	 */
	public String getMemberId() {
		return memberId;
	}

	/**
	 * @param memberId the memberId to set
	 */
	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}

	/**
	 * @return the fromChannel
	 */
	public String getFromChannel() {
		return fromChannel;
	}

	/**
	 * @param fromChannel the fromChannel to set
	 */
	public void setFromChannel(String fromChannel) {
		this.fromChannel = fromChannel;
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * @return the shortDesc
	 */
	public String getShortDesc() {
		return shortDesc;
	}

	/**
	 * @param shortDesc the shortDesc to set
	 */
	public void setShortDesc(String shortDesc) {
		this.shortDesc = shortDesc;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the questionType
	 */
	public String getQuestionType() {
		return questionType;
	}

	/**
	 * @param questionType the questionType to set
	 */
	public void setQuestionType(String questionType) {
		this.questionType = questionType;
	}

	public String page() {
		if (iamlazy != null && "viewQuestion".equals(iamlazy)) {
			// 檢測是否設定工單處理開始時間, 若owner是自已，且開始時間沒有設 定，則設 定開始時間
			// 原則上只有回單會有這個問題，其他情況都是以〝取得〝時為開始時間
			if (id != null) {
				WorkOrder workOrder = (WorkOrder) baseMgr.get(WorkOrder.class, JspUtil.toLong(id));
				if (workOrder.getOwner() != null) {
					// 若owner是自已
					if (workOrder.getOwner().getUsername().equals(JspUtil.username())) {
						// 若尚未有開始時間
						if (workOrder.getStartTime() == null) {
							workOrder.setStartTime(new Date());
							baseMgr.update(workOrder);
						}
					}
				}
			}
		}
		if (AJAX != null && AJAX.equals("true")) {
			return iamlazy + "_ajax";
		} else {
			return iamlazy;
		}
	}

	private String returnPage(String orgPage) {
		if (AJAX != null && AJAX.equals("true")) {
			return orgPage + "_ajax";
		} else {
			return orgPage;
		}
	}

	@Transactional(propagation = Propagation.NESTED)
	public String createOrderAndQuestion() {
		updateQuestion();
		boolean isProcessing = false;
		WorkOrder theLastWo = null;
		if (orgQuestionId != null && orgQuestionId.length() > 0) {
			Object[] wos = baseMgr.queryByHql("from WorkOrder where domainId=? order by id desc",
					new Object[] { orgQuestionId }, 0, 1);
			theLastWo = null;
			if (wos != null && wos.length > 0) {
				theLastWo = (WorkOrder) wos[0];
			}
			if (theLastWo != null) {
				if (theLastWo.getStatus() == WorkOrder.STATUS.INIT.value() && theLastWo.getOwner() != null) {
					// 初始状态, 且已被取得, 建立一新工单，状态为完成
					isProcessing = true;
				}
			}
		}
		if (isProcessing) {
			// 建立一新工单，状态为完成
			WorkOrder newWo = new WorkOrder();
			BeanUtils.copyProperties(theLastWo, newWo);
			newWo.setCreateDate(new Date());
			newWo.setModifyDate(newWo.getCreateDate());
			newWo.setOwner(null);
			newWo.setComment(comment);
			newWo.setPriority(Integer.parseInt(priority));
			newWo.setStatus(WorkOrder.STATUS.SUCCESS.value());
			newWo.setStartTime(newWo.getCreateDate());
			newWo.setFinishTime(newWo.getCreateDate());
			newWo.setApproveStatus(WorkOrder.APPROVE_STATUS.APPROVED.value());
			newWo.setApproveTime(newWo.getCreateDate());
			newWo.setFromWorkOrder(preWorkOrder);
			baseMgr.save(newWo);
		} else {
			User user = (User) baseMgr.get(User.class, AdminHelper.getUser().getUsername());
			preWorkOrder.setOwner(user);
			baseMgr.update(preWorkOrder);

			workOrderService.forwardOrder(String.valueOf(preWorkOrder.getId()), comment, responser, workFlowNodeId, Integer
					.parseInt(priority));
		}
		if (fromManage != null && fromManage.equals("true")) {
			return returnPage("forwardToViewQuestion");
		}
		return returnPage("createOrderAndQuestion");
	}

	private WorkOrder preWorkOrder;

	@Transactional(propagation = Propagation.NESTED)
	public String updateQuestion() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

		try {
			UserDetails user = AdminHelper.getUser();

			QuestionType qt = null;
			if (questionType != null && questionType.length() > 0) {
				qt = (QuestionType) baseMgr.get(QuestionType.class, questionType);
			}

			FromChannel fc = null;
			if (fromChannel != null && fromChannel.length() > 0) {
				fc = new FromChannel();
				fc.setId(fromChannel);
			}

			Question question = csService.createQuestionBase(id, orgQuestionId, questionType, request.getParameterMap(),
					description, comment, fc, user.getUsername());
			if (!question.getId().equals(orgQuestionId)) {

				if ("newOrder".equals(forward)) {
					// 检查是否已结单
					if (question.getStatus() == 2) {
						// do nothing
					} else {
						// 结束原问题单工单（留下endtime栏位不填）
						Object[] wos = baseMgr.queryByHql("from WorkOrder where domainId=?", new Object[] { Long
								.valueOf(orgQuestionId) });
						for (Object obj : wos) {
							WorkOrder wo = (WorkOrder) obj;
							if (wo.getStatus() == WorkOrder.STATUS.SUCCESS.value()) {
								continue;
							}
							wo.setStatus(WorkOrder.STATUS.SUCCESS.value());
							// 代结
							wo.setFinishType(WorkOrder.FINISH_TYPE.PROXY.value());
							wo.setComment(wo.getComment() + "自动结单；代结：" + AdminHelper.getUser().getUsername());
						}
					}

				}
				qt = (QuestionType) baseMgr.get(QuestionType.class, qt.getName());
				if (id == null || id.length() == 0) {
					preWorkOrder = workOrderService.createWorkOrder("SYSTEM", question.getId(), question.getShortDesc(), false,
							null);
				}
				if (preWorkOrder == null) {
					preWorkOrder = (WorkOrder) baseMgr.get(WorkOrder.class, Long.parseLong(workOrderId));
				}
			} else {
				Object[] wos = baseMgr.queryByHql("from WorkOrder where domainId=? order by id desc",
						new Object[] { orgQuestionId }, 0, 1);

				if (wos != null && wos.length > 0) {
					preWorkOrder = (WorkOrder) wos[0];
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return returnPage("updateQuestion");
	}

	public String index() {
		return returnPage("index");
	}

	public String updateCommonQuestionType() {
		CommonQuestionType cqt = null;
		if (id == null || id.length() == 0) {
			cqt = new CommonQuestionType();
			if (parentId != null && parentId.length() > 0) {
				CommonQuestionType cqtParent = new CommonQuestionType();
				cqtParent.setId(parentId);
				cqt.setParent(cqtParent);
			}
		} else {
			cqt = (CommonQuestionType) baseMgr.get(CommonQuestionType.class, id);
		}
		cqt.setName(name);
		cqt.setDescription(description);
		if (workFlowName != null && workFlowName.length() > 0) {
			cqt.setWorkFlowName(workFlowName);
		}
		cqt.setShowOnQAA(Boolean.valueOf(showOnQAA));
		baseMgr.saveOrUpdate(cqt);

		return returnPage("updateCommonQuestionType");
	}

	public String deleteCommonQuestionType() {
		CommonQuestionType cqt = (CommonQuestionType) baseMgr.get(CommonQuestionType.class, id);
		if (cqt.getChilds() != null && cqt.getChilds().size() > 0) {
			sysMessage = "请先删除子类";
			return returnPage("questionClassEdit");
		} else {
			baseMgr.delete(cqt);
			return returnPage("questionClass");
		}
	}

	private File file;
	private String reason;
	private String message;

	public String outOfStockBatch() {
		try {
			List<String> orderAndProductList = null;
			if (file != null) {
				FileInputStream fis = new FileInputStream(file);
				BufferedReader bd = new BufferedReader(new InputStreamReader(fis));
				String line = "";
				orderAndProductList = new ArrayList<String>();
				while ((line = bd.readLine()) != null) {
					if (line.length() != 0) {
						orderAndProductList.add(line);
					}
				}
				fis.close();
				bd.close();
			}
			String[] strs = new String[orderAndProductList.size()];
			csService.forwardOrderForOutOfStockInternalBatch(orderAndProductList.toArray(strs), reason, comment, AdminHelper
					.getUser().getUsername());
		} catch (Exception e) {
			e.printStackTrace();
			message = "批次产生断／缺货工单时发生错误！";
		}
		return "outOfStockBatch";
	}

	/**
	 * @return the aJAX
	 */
	public String getAJAX() {
		return AJAX;
	}

	/**
	 * @param aJAX the aJAX to set
	 */
	public void setAJAX(String aJAX) {
		AJAX = aJAX;
	}

	/**
	 * @return the batchOrderList
	 */
	public String getBatchOrderList() {
		return batchOrderList;
	}

	/**
	 * @param batchOrderList the batchOrderList to set
	 */
	public void setBatchOrderList(String batchOrderList) {
		this.batchOrderList = batchOrderList;
	}

	/**
	 * @return the successBatch
	 */
	public int getSuccessBatch() {
		return successBatch;
	}

	/**
	 * @param successBatch the successBatch to set
	 */
	public void setSuccessBatch(int successBatch) {
		this.successBatch = successBatch;
	}

	public String saveBatchWorkOrder() {
		successBatch = 0;
		readOrders = 0;
		failBatch = 0;
		try {
			// InputStream inputStream = new FileInputStream(batchOrderList);
			// CsvReader reader = new CsvReader(inputStream, ',', Charset.forName("UTF-8"));
			// if (reader.readHeaders()) {
			//
			// while (reader.readRecord()) {
			if (StringUtils.isNotBlank(batchOrderList)) {
				batchOrderList = StringUtils.replace(batchOrderList, "\n", ",");
				ArrayList<String> orderIds = new ArrayList<String>(Arrays.asList(StringUtils.split(batchOrderList, ",")));
				readOrders = orderIds.size();
				for (String orderId : orderIds) {
					Orders order = orderService.get(orderId.trim());
					if (null != order) {
						csService.createCommonQuestionFromInternal(order.getReceiverEmail(), order.getMemberId(), "", description,
								order.getReceiverPhoneArea(), order.getReceiverPhone(), order.getReceiverExt(), order.getOrderId(),
								order.getReceiverMobile(), class1, class2, commonQuestionType, workFlowNodeId, Integer
										.parseInt(priority), "", "");
						successBatch++;
					} else {
						failBatch++;
					}

				}
			}
			// }
			// }

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return returnPage("questionBatch");
	}

	/**
	 * @return the file
	 */
	public File getFile() {
		return file;
	}

	/**
	 * @param file the file to set
	 */
	public void setFile(File file) {
		this.file = file;
	}

	/**
	 * @return the reason
	 */
	public String getReason() {
		return reason;
	}

	/**
	 * @param reason the reason to set
	 */
	public void setReason(String reason) {
		this.reason = reason;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * @return the readOrders
	 */
	public int getReadOrders() {
		return readOrders;
	}

	/**
	 * @param readOrders the readOrders to set
	 */
	public void setReadOrders(int readOrders) {
		this.readOrders = readOrders;
	}

	/**
	 * @return the failBatch
	 */
	public int getFailBatch() {
		return failBatch;
	}

	/**
	 * @param failBatch the failBatch to set
	 */
	public void setFailBatch(int failBatch) {
		this.failBatch = failBatch;
	}

	public String newOrder() {
		Question question = (Question) baseMgr.get(Question.class, questionId);

		if (question.getStatus() == 2) {
			message = "该工单已结单";
			return "question";
		} else {
			// 尚未完成，产生新的工单
			message = "已成立新工单";
			workOrderService.newOrder(Long.valueOf(workOrderId), AdminHelper.getUser().getUsername());
		}
		return "newOrder";
	}
}
